import { ESGeoLineString, ESGeoPolygon, ESGeoVector, ESTextLabel, ESObjectWithLocation } from 'esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main';
import { SceneTreeItem } from "xbsj-xe2/dist-node/xe2";
import { XbsjEarthUi } from "../../scripts/xbsjEarthUi";
function createSceneObjByJson(obj: { [key: string]: any }, xbsjEarthUi: XbsjEarthUi) {
    const sceneTree = xbsjEarthUi.getSceneTree()
    if (!sceneTree) return
    if (obj['sceneObj']) {
        const a = obj['sceneObj']
        const treeItem = sceneTree.createSceneObjectTreeItemFromJson(a)
        if (treeItem) {
            sceneTree.uiTree.clearAllSelectedItems()
            treeItem.uiTreeObject.selected = true
        }
    }
    if (obj['children']) {
        for (let i = 0; i < obj['children'].length; i++) {
            createSceneObjByJson(obj['children'][i], xbsjEarthUi);
        }
    }
}
export function meargeObj(root: string, xbsjEarthUi: XbsjEarthUi) {
    const a = JSON.parse(root)
    const obj = a.sceneTree.root
    if (obj) {
        createSceneObjByJson(obj, xbsjEarthUi);
    }
}

export function geojsonToPointsLinesPolygons(geojson: any) {
    var result = {
        points: [],
        lines: [],
        polygons: []
    };
    if (geojson.type === 'FeatureCollection') {
        geojson.features.forEach(function (feature: { geometry: any; properties: any }) {
            convertGeometry(feature.geometry, result, feature.properties);
        });
    } else {
        convertGeometry(geojson, result);
    }
    return result;
}
function convertGeometry(geometry: { type: any; coordinates: any[]; geometries: any[]; geometry: any; }, result: { points: any; lines: any; polygons: any; }, properties?: any) {
    // console.log('properties', properties);

    switch (geometry.type) {
        case 'Point':
            result.points.push({ coordinates: geometry.coordinates, properties });
            break;
        case 'MultiPoint':
            geometry.coordinates.forEach(function (point: any[], index) {
                result.points.push({ coordinates: point, properties }); // Assuming exterior ring
            });
            break;
        case 'LineString':
            result.lines.push(geometry.coordinates);
            break;
        case 'MultiLineString':
            geometry.coordinates.forEach(function (line: any[]) {
                result.lines.push(line); // Assuming exterior ring
            });
            break;
        case 'Polygon':
            geometry.coordinates.forEach(function (polygon: any[]) {
                // result.polygons.push(polygon); // Assuming exterior ring
                result.polygons.push({ polygon, properties }); // Assuming exterior ring
            });
            break;
        case 'MultiPolygon':
            geometry.coordinates.forEach(function (polygon: any[]) {
                result.polygons.push({ polygon: polygon[0], properties }); // Assuming exterior ring
            });
            break;
        case 'GeometryCollection':
            geometry.geometries.forEach(function (geom: any) {
                convertGeometry(geom, result);
            });
            break;
        default:
            convertGeometry(geometry.geometry, result);
    }
}
export function createLines(xbsjEarthUi: XbsjEarthUi, lines: any, linesGroup: SceneTreeItem) {
    lines.forEach((element: any) => {
        // console.log('createLines', element);
        let points: [number, number, number][] = []
        element.forEach((item: [number, number] | [number, number, number]) => {
            if (item.length === 2) {
                points.push([...item, 0])
            } else if (item.length === 3) {
                points.push(item)
            }
        })
        const treeItem = xbsjEarthUi.createSceneObjectTreeItem('ESGeoLineString', undefined, linesGroup, 'Inner') as SceneTreeItem
        const sceneObject = treeItem.sceneObject as ESGeoLineString
        sceneObject.points = points
        sceneObject.strokeStyle = {
            "width": 1,
            "widthType": "screen",
            "color": [
                0.7137254901960784,
                0.8274509803921568,
                0.10196078431372549,
                1
            ],
            "material": "",
            "materialParams": {}
        }
    });
}
export function createpoints(xbsjEarthUi: XbsjEarthUi, points: any, pointsGroup: SceneTreeItem) {
    points.forEach((element: any, index: number) => {
        // console.log('createpoints', element);
        const position = element.coordinates.length === 2 ? [...element.coordinates, 0] as [number, number, number] : element.coordinates
        const treeItem = xbsjEarthUi.createSceneObjectTreeItem('ESTextLabel', undefined, pointsGroup, 'Inner') as SceneTreeItem
        const sceneObject = treeItem.sceneObject as ESTextLabel
        sceneObject.position = position

        if (element.properties && element.properties.NAME) {
            sceneObject.text = element.properties.NAME
            sceneObject.name = element.properties.NAME
        } else {
            sceneObject.text = `点位${index + 1}`
            sceneObject.name = `点位${index + 1}`
        }
    });
}
export function createpolygons(xbsjEarthUi: XbsjEarthUi, polygons: any, polygonsGroup: SceneTreeItem) {
    polygons.forEach((element: any, index: number) => {
        // console.log('createpolygons', element);
        let points: [number, number, number][] = []
        element.polygon.forEach((item: [number, number] | [number, number, number]) => {
            if (item.length === 2) {
                points.push([...item, 0])
            } else if (item.length === 3) {
                points.push(item)
            }
        })
        const treeItem = xbsjEarthUi.createSceneObjectTreeItem('ESGeoPolygon', undefined, polygonsGroup, 'Inner') as SceneTreeItem
        const sceneObject = treeItem.sceneObject as ESGeoPolygon
        sceneObject.points = points
        // sceneObject.materialMode = "cord"
        if (element.properties && element.properties.NAME) {
            sceneObject.name = element.properties.NAME
        } else {
            sceneObject.name = `多边形${index + 1}`
        }
        sceneObject.stroked = true
        sceneObject.strokeStyle = {
            "width": 1,
            "widthType": "screen",
            "color": [
                0.6235294117647059,
                0.7294117647058823,
                0.08627450980392157,
                1
            ],
            "material": "",
            "materialParams": {}
        }
        sceneObject.filled = true
        sceneObject.fillStyle = {
            "color": [
                0.788235294117647,
                0.9098039215686274,
                0.058823529411764705,
                0.2
            ],
            "material": "",
            "materialParams": {},
            "ground": false
        }
    });
}
//获取所有 路径对象 
function searchPoints(xbsjEarthUi: XbsjEarthUi, obj: { [key: string]: any }, result: any) {
    if (obj['sceneObj']) {
        const sceneObject = xbsjEarthUi.getSceneObjectById(obj['sceneObj'].id)
        if (sceneObject instanceof ESObjectWithLocation) {
            const a = {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": sceneObject.position
                }
            }
            result.features.push(a)
        } else if (sceneObject instanceof ESGeoLineString) {
            const a = {
                "type": "Feature",
                "geometry": {
                    "type": "LineString",
                    "coordinates": sceneObject.points
                }
            }
            result.features.push(a)
        }
        else if (sceneObject instanceof ESGeoVector) {
            const a = {
                "type": "Feature",
                "geometry": {
                    "type": "Polygon",
                    "coordinates": [sceneObject.points]
                }
            }
            result.features.push(a)
        }
    }
    if (obj['children']) {
        for (let i = 0; i < obj['children'].length; i++) {
            searchPoints(xbsjEarthUi, obj['children'][i], result);
        }
    }
}
export function searchForLineValues(xbsjEarthUi: XbsjEarthUi, json: { [key: string]: any }) {
    var result = {
        "type": "FeatureCollection",
        "features": []
    };
    if (json) {
        searchPoints(xbsjEarthUi, json, result)
    }
    return result
}


//保存到本地
export type FileHandleType = {
    readonly kind: string;
    readonly name: string;
};
const acceptsOptions = {
    json: {
        description: 'JSON Files',
        accept: {
            'text/json': '.json',
        },
    },
    js: {
        description: 'JS Files',
        accept: {
            'text/js': '.js',
        },
    },
    txt: {
        description: 'Text Files',
        accept: {
            'text/plain': ['.txt', '.text'],
        },
    },
    geoJson: {
        description: 'geoJson Files',
        accept: {
            'text/geoJson': '.geoJson',
        },
    },
}
export async function saveFileHandle(type?: 'txt' | 'js' | 'json' | 'geoJson', suggestedName?: string) {
    const option = acceptsOptions[type ?? 'json']
    try {
        // @ts-ignore
        const handle = await showSaveFilePicker({
            suggestedName: suggestedName ?? `未命名.${type ?? "json"}`,
            types: [option],
        });
        return handle as FileHandleType | undefined;
    } catch (error) {
        console.warn(`getSaveFileHandle error: ${error}`);
        return undefined;
    }
}
export async function save(handle: FileHandleType, str: string) { //.js .txt .json都可使用
    const blob = new Blob([str], { type: "text/plain;charset=utf-8", });
    // @ts-ignore
    const writable = await handle.createWritable();
    await writable.write(blob);
    await writable.close();
}